﻿using BootyBay.PrivateStoreApp.DataModel;
using BootyBay.PrivateStoreApp.StoreServicesRef;
using HtmlAgilityPack;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using System.Text;
using System.Threading.Tasks;
using Windows.Storage;
using Windows.Storage.Streams;
using Windows.System;
using Windows.UI.Popups;

namespace BootyBay.PrivateStoreApp.ViewModels
{
    public class AppListPageVM
    {

        #region Instance
        private static AppListPageVM instance = null;

        public static AppListPageVM Instance
        {
            get
            {
                if (instance == null)
                {
                    instance = new AppListPageVM();
                }
                return instance;
            }
        }
        #endregion

        public AppListPageVM()
        {
            m_SvcClient = new StoreServicesClient();
        }

        #region 对象声明

        StoreServicesClient m_SvcClient;

        private ObservableCollection<UserAppDataModel> m_AppData = new ObservableCollection<UserAppDataModel>();
        public ObservableCollection<UserAppDataModel> AppData
        {
            get
            {
                return m_AppData;
            }
        }
        private ObservableCollection<UserAppDataModel> m_CategoryAppData = new ObservableCollection<UserAppDataModel>();
        public ObservableCollection<UserAppDataModel> CategoryAppData
        {
            get
            {
                return m_CategoryAppData;
            }
        }
        private ObservableCollection<UserAppDataModel> m_PromotionalAppData = new ObservableCollection<UserAppDataModel>();
        public ObservableCollection<UserAppDataModel> PromotionalAppData
        {
            get
            {
                return m_PromotionalAppData;
            }
        }
        private ObservableCollection<UserAppDataModel> m_RecommendAppData = new ObservableCollection<UserAppDataModel>();
        public ObservableCollection<UserAppDataModel> RecommendAppData
        {
            get
            {
                return m_RecommendAppData;
            }
        }
        private UserAppDataModel m_AppModelImage = new UserAppDataModel(new View_Application());
        public UserAppDataModel AppModelImage
        {
            get
            {
                return m_AppModelImage;
            }
        }
        public string UserName
        {
            get { return App.CurrentUserName; }
        }

        private bool m_IsLoadingInfo = false;
        public bool IsLoadingInfo
        {
            get
            {
                return m_IsLoadingInfo;
            }
        }
        #endregion

        #region 获取主页应用列表
        public async void GetApps()
        {
            //从服务器获取全部数据
            var allAppData_list = await m_SvcClient.GetAllAppInfoDataAsync();

            //获取最新上传的5个应用作为主页推广显示使用
            PromotionalAppData.Clear();
            foreach (var app in allAppData_list)
            {
                if (app.ApplicationName == "建设银行" || app.ApplicationName == "Lizard医生移动查房系统" || app.ApplicationName == "掌上东航" || app.ApplicationName == "Study Centre" || (app.ApplicationName == "宇通客车" && app.DisplayName != "YutongDemo"))
                {
                    UserAppDataModel appModel = new UserAppDataModel(app);
                    #region 将应用的图片列表第一张图片设置成应用主页显示的图片
                    if (app.ScreenshotUrlList.Count > 0)
                    {
                        appModel.AppView.ScreenshotUrls = app.ScreenshotUrlList[0];
                    }
                    #endregion
                    if (app.IsPublicApp)
                    {
                        appModel = await Parse(app);
                    }
                    PromotionalAppData.Add(appModel);
                }

            }
            //获取最新上传的并且是推荐的5个应用作为主页推荐显示使用
            RecommendAppData.Clear();
            var allAppData2 = allAppData_list.OrderByDescending(u => u.CreationDate).Where(u => u.IsRecommended = true).Take(5);
            foreach (var app in allAppData2)
            {
                UserAppDataModel appModel = new UserAppDataModel(app);
                RecommendAppData.Add(appModel);
            }
            m_IsLoadingInfo = true;
            foreach (UserAppDataModel item in RecommendAppData)
            {
                if (item.AppView.IsPublicApp)
                {
                    UserAppDataModel appModel = new UserAppDataModel(item.AppView);
                    appModel = await Parse(item.AppView);
                }
            }


            AppData.Clear();
            foreach (var app in allAppData_list)
            {
                UserAppDataModel appModel = new UserAppDataModel(app);
                m_AppData.Add(appModel);//保存所有数据
            }
        }
        #endregion

        #region 获取推荐应用列表
        /// <summary>
        /// 获取主页推荐应用列表
        /// </summary>
        public async void GetMainRecommendApps()
        {
            var allAppData = await m_SvcClient.GetRecommendedAppsAsync();
            RecommendAppData.Clear();
            foreach (var app in allAppData)
            {
                UserAppDataModel appModel = new UserAppDataModel(app);
                RecommendAppData.Add(appModel);
            }
        }
        public ObservableCollection<UserAppDataModel> GetAllRecommendApps()
        {
            ObservableCollection<UserAppDataModel> list = new ObservableCollection<UserAppDataModel>();
            foreach (var app in AppData)
            {
                if (app.AppView.IsRecommended)
                {
                    list.Add(app);
                }
            }
            return list;
        }
        #endregion

        #region 将服务器应用保存到本地目录

        private async void SavePackageToLocal(string name, string url)
        {
            try
            {
                StorageFolder RootFolder = Windows.Storage.ApplicationData.Current.LocalFolder;
                bool IsExistFolderAll = false;
                StorageFolder FolderAll = null;
                try
                {
                    FolderAll = await RootFolder.CreateFolderAsync("AllApps");
                }
                catch (Exception)
                {
                    IsExistFolderAll = true;
                }
                if (!IsExistFolderAll)
                {
                    //FolderAll = await RootFolder.CreateFolderAsync("AllApp");
                }
                else
                {
                    FolderAll = await RootFolder.GetFolderAsync("AllApps");
                }


                string packageName = url.Substring(url.LastIndexOf("."));
                bool IsExistFiles = true;
                try
                {
                    StorageFile storageFile = await FolderAll.GetFileAsync(name + packageName);
                }
                catch (Exception)
                {
                    IsExistFiles = false;
                }
                if (!IsExistFiles)
                {
                    var rass = RandomAccessStreamReference.CreateFromUri(new Uri(url));
                    IRandomAccessStreamWithContentType streamRandom = await rass.OpenReadAsync();
                    IBuffer buffer = RandomAccessStreamToBuffer(streamRandom);
                    StorageFile storageFile = await FolderAll.CreateFileAsync(name + packageName, CreationCollisionOption.ReplaceExisting);
                    await FileIO.WriteBufferAsync(storageFile, buffer);
                    streamRandom.Dispose();
                }

            }
            catch (System.IO.FileNotFoundException ex)
            {
            }
        }

        /// <summary>
        /// 将IRandomAccessStream文件转换成Ibuffer文件
        /// </summary>
        /// <param name="randomstream"></param>
        /// <returns></returns>
        public static IBuffer RandomAccessStreamToBuffer(IRandomAccessStream randomstream)
        {

            Stream stream = WindowsRuntimeStreamExtensions.AsStreamForRead(randomstream.GetInputStreamAt(0));

            MemoryStream memoryStream = new MemoryStream();
            if (stream != null)
            {
                byte[] bytes = ConvertStreamTobyte(stream);
                if (bytes != null)
                {
                    var binaryWriter = new BinaryWriter(memoryStream);
                    binaryWriter.Write(bytes);
                }
            }
            IBuffer buffer = WindowsRuntimeBufferExtensions.GetWindowsRuntimeBuffer(memoryStream, 0, (int)memoryStream.Length);
            return buffer;
        }

        /// <summary>
        /// 将Stream文件转换成byte[]
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public static byte[] ConvertStreamTobyte(Stream input)
        {
            byte[] buffer = new byte[16 * 1024];

            using (MemoryStream ms = new MemoryStream())
            {
                int read;
                while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
                {
                    ms.Write(buffer, 0, read);
                }
                return ms.ToArray();
            }
        }

        #endregion

        #region 从服务器获取数据
        public async void LoadAppData()
        {
            try
            {
                var allAppData = await m_SvcClient.GetAllAppInfoDataAsync();
                GetMainRecommendApps();
                AppData.Clear();
                foreach (var app in allAppData)
                {
                    UserAppDataModel appModel = new UserAppDataModel(app);
                    //app.Category = 7;//相关应用数据测试使用
                    m_AppData.Add(appModel);

                    #region 将服务器应用备份到本地，暂时不调用
                    //var files = await m_SvcClient.GetPackageUrlAsync(appModel.AppView.Id_ApplicationVersion, Convert.ToInt32(appModel.AppView.ProcessorArchitectureList[0]));
                    //if (files != null)
                    //{
                    //    SavePackageToLocal(appModel.AppView.DisplayName, files.PackageCertLocationUrl);
                    //    SavePackageToLocal(appModel.AppView.DisplayName, files.PackageLocationUrl);
                    //}
                    #endregion
                }
            }
            catch
            {
                MessageDialog errorMsg = new MessageDialog("Please start the private store agent service", "Agent is not available");
                errorMsg.ShowAsync();
            }
        }
        #endregion

        #region 条件查询服务器数据(搜索/相关应用)
        public async void LoadAppData(string paras, UserAppDataModel userAppDataModel, string str)
        {
            //CategoryAppData.Clear();
            if (paras != null)
            {
                if (userAppDataModel.AppView == null)
                {
                    CategoryAppData.Clear();
                    var allAppData = await m_SvcClient.GetAllAppInfoDataAsync();
                    foreach (var app in allAppData)
                    {
                        if (app.ApplicationName.ToLower().IndexOf(paras) != -1 || (app.Keywords != null && app.Keywords.ToLower().Split(';').Contains(paras.ToLower())))
                        {
                            UserAppDataModel model = new UserAppDataModel(app);
                            m_CategoryAppData.Add(model);
                        }
                    }
                }
                else
                {
                    CategoryAppData.Clear();
                    ObservableCollection<UserAppDataModel> userappData = await AppCategoriesPageVM.Instance.GetAppsByCategories(userAppDataModel.AppView.Category);
                    string[] para = paras.Split(';');
                    foreach (var app in userappData)//循环加载私有应用
                    {
                        foreach (var item in para)
                        {
                            if (item.ToString().Trim() != "" && app.AppView.Keywords != null)
                            {
                                if (app.AppView.Keywords.ToLower().Split(';').Contains(item.ToLower()) == true && app.AppView.ApplicationName != userAppDataModel.AppView.ApplicationName)
                                {
                                    var isExistApp = m_CategoryAppData.Where(a => a.AppView.ApplicationName == app.AppView.ApplicationName).FirstOrDefault();
                                    if (isExistApp == null)
                                    {
                                        if (str == "all")//相关应用页--显示该应用的全部相关应用
                                        {
                                            m_CategoryAppData.Add(app);
                                        }
                                        else
                                        {
                                            if (m_CategoryAppData.Count < 4)//应用的详细页--只显示该应用的4个相关应用
                                            {
                                                m_CategoryAppData.Add(app);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                try
                {
                    foreach (UserAppDataModel item in CategoryAppData)
                    {
                        if (item.AppView.IsPublicApp)
                        {
                            UserAppDataModel appModel = new UserAppDataModel(item.AppView);
                            appModel = await AppListPageVM.Instance.Parse(item.AppView);
                        }
                    }
                }
                catch (Exception)
                {
                }

            }
        }
        #endregion

        #region 根据ID查询数据
        public async Task<UserAppDataModel> GetItemAsync(int Id)
        {
            UserAppDataModel appModel = null;
            try
            {
                var allAppData = await m_SvcClient.GetAllAppInfoDataAsync();

                AppData.Clear();
                foreach (var app in allAppData)
                {
                    if (app.Id == Id)
                    {
                        appModel = new UserAppDataModel(app);
                        break;
                    }

                }
            }
            catch
            {
            }
            return appModel;
        }
        #endregion


        #region 判断是否为公有应用
        public async Task<UserAppDataModel> Parse(View_Application app)
        {
            UserAppDataModel appModel = new UserAppDataModel(app);

            HtmlWeb webClient = new HtmlWeb();
            HtmlDocument htmlDocument = await webClient.LoadFromWebAsync(app.StoreHttpUrl);

            // Parse html node, this is a recursive function which call itself until
            // all the childs of html document has been navigated and parsed.
            HtmlNode htmlNode = htmlDocument.DocumentNode;
            //获得packageFamilyName 
            HtmlNode scriptName =
              (from el in htmlNode.Descendants("script")
               select el).ToList()[7];
            string scriptText = scriptName.InnerText;
            int index = scriptText.IndexOf("packageFamilyName = '");
            if (index != -1)
            {
                string packName = scriptText.Substring(index + 21);
                string m_PackName = packName.Substring(0, packName.IndexOf("'"));

                int index2 = scriptText.IndexOf("publisherName = '");
                string packName2 = scriptText.Substring(index2 + 17);
                string publisherDisplayName = packName2.Substring(0, packName2.IndexOf("'"));

                string documentAlltext = htmlNode.InnerHtml;
                int index3 = documentAlltext.IndexOf("id=\"ScreenshotImage\" src=\"");
                string packName3 = documentAlltext.Substring(index3 + 26);
                string sreenshotImage = packName3.Substring(0, packName3.IndexOf("\""));

                //获得appName
                HtmlNode list1 =
                   (from el in htmlNode.Descendants("h1")
                    where (string)el.GetAttributeValue("id", "ProductTitleText") == "ProductTitleText"
                    select el).First();

                string appName = list1.InnerText;

                //获得storlogo
                IEnumerable<HtmlNode> logos =
                    (from el in htmlNode.Descendants("meta")

                     select el);

                HtmlNode logo = logos.ToList()[12];
                string storelogo = logo.GetAttributeValue("content", "123");


                appName = appName.Replace("&#176;", "°");
                appName = appName.Replace("&amp;", "&");
                //appModel.AppView.ApplicationName = appName;
                appModel.AppView.LogoUrl_150x150 = storelogo;
                appModel.AppView.PublisherDisplayName = publisherDisplayName;
                appModel.AppView.ScreenshotUrls = sreenshotImage;
                appModel.AppView.Publisher = m_PackName;
            }
            else
            {

            }
            return appModel;
        }
        #endregion

        #region 跳转到公有商店应用详细页面
        public async void OpenPublicAppDetailPage(string pfn)
        {
            Uri uri = new Uri("ms-windows-store:PDP?PFN=" + pfn);
            bool falg = await Launcher.LaunchUriAsync(uri);
        }
        #endregion
    }
}
